import os
import globalPluginHandler, tones, ui
from gui.settingsDialogs import NVDASettingsDialog
from keyboardHandler import KeyboardInputGesture
from . import adb, constants, settings, speech, virtualMenus, watcher
from synthDrivers import nvbox
# 虚拟菜单的基本手势
menuGestures = {
  'kb:uparrow': 'prev',
  'kb:downarrow': 'next',
  'kb:leftarrow': 'prevCategory',
  'kb:rightarrow': 'nextCategory',
  'kb:enter': 'activate',
  'kb:space': 'activate',
  'kb:home': 'first',
  'kb:end': 'last',
  'kb:NVDA+z': 'cancel'
}
# 宝盒的默认手势
entryGestures = {
  'kb:NVDA+z': 'showVirtualMenus'
}
# 虚拟菜单项目字典
menuScripts = {}
# 从文件加载菜单数据
with open (os.path.join (os.path.dirname (__file__), 'virtualMenus.txt'), 'r', encoding = constants.CHARSET) as f:
    for line in f.readlines():
        line = line.strip ()
        if line.startswith ('#'):continue
        title, key, func, category = line.split ('\t')
        if not category in menuScripts.keys():
            menuScripts[category] = []
        menuScripts[category].append((title, key, func,))
#NVDA的全局插件的处理器类
class GlobalPlugin(globalPluginHandler.GlobalPlugin):
    scriptCategory = constants.SUMMARY
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 添加NV宝盒语音合成器菜单
        nvbox.initMenus()
        # 注册设置页面
        NVDASettingsDialog.categoryClasses.append(settings.SettingsPanel)
        # 语音朗读扩展
        speech.work()
        # 无线连接安卓设备（如果有）
        adb.connect()
        # 对象监视器
        watcher.init()
        # 绑定入口手势
        self.bindGestures (entryGestures)
        # 菜单索引
        self.menuIndex = 0
        # 没有菜单为 True
        self.hasNoMenus = True
        self._mouseObject = None
    def terminate(self):
        super().terminate()
        # 解除NV宝盒语音合成器菜单
        nvbox.destroyMenus()
        # 解除设置页面
        NVDASettingsDialog.categoryClasses.remove(settings.SettingsPanel)
        # 杀死 ADB 服务
        adb.killServer()
        # 释放对象监视器
        watcher.release ()
        # 清空手势
        self.clearGestureBindings ()
        # 解除语音朗读扩展
        speech.rest()
    def event_mouseMove(self, obj, nextHandler, x, y):
        nextHandler()
        return
        if obj != self._mouseObject:
            self._mouseObject = obj
            try:
                ui.message(obj.IA2Attributes['class'])
            except:pass
        nextHandler()
    # 显示虚拟菜单
    def script_showVirtualMenus(self, gesture):
        # 清空手势
        self.clearGestureBindings ()
        categoryIndex = settings.getMenuCategory()
        category = list(menuScripts.keys())[categoryIndex]
        self.menuScripts = menuScripts[category]
        def func(x, y):
            for menu in self.menuScripts:
                if y.mainKeyName.lower() == menu[1]:
                    x.cancelVirtualMenus ()
                    exec(f'virtualMenus.menu_{menu[2]}()')
                    return
        # 将虚拟菜单项目的快捷键填充到菜单基本手势里面
        gestures = menuGestures.copy()
        for menu in self.menuScripts:
            exec(f'GlobalPlugin.script_{menu[2]} = func')
            gestures['kb:%s' % menu[1]] = menu [2]
        # 绑定菜单手势
        self.bindGestures (gestures)
        l = len (self.menuScripts)
        if self.menuIndex < 0:
            self.menuIndex = l -1
        elif self.menuIndex >= l:
            self.menuIndex = 0
        menu = ','.join (self.menuScripts[self.menuIndex])
        ui.message (f'{category},{menu},菜单')
    script_showVirtualMenus.__doc__ = _('显示宝盒虚拟菜单')
    # 虚拟菜单上一个分类的处理
    def script_prevCategory(self, gesture):
        categoryIndex = settings.getMenuCategory() -1
        if categoryIndex < 0:
            categoryIndex = len(menuScripts.keys()) -1
            tones.beep (300, 40)
        settings.setMenuCategory(categoryIndex)
        self.script_showVirtualMenus(gesture)
    # 虚拟菜单下一个分类的处理
    def script_nextCategory(self, gesture):
        categoryIndex = settings.getMenuCategory() + 1
        if categoryIndex >= len(menuScripts.keys()):
            categoryIndex = 0
            tones.beep (300, 40)
        settings.setMenuCategory(categoryIndex)
        self.script_showVirtualMenus(gesture)
    # 虚拟菜单上一项的处理
    def script_prev(self, gesture):
        index = self.menuIndex -1
        if index < 0:
            self.script_last (gesture)
            return
        self.menuIndex = index
        ui.message (','.join (self.menuScripts[index]))
    # 虚拟菜单下一项的处理
    def script_next(self, gesture):
        index = self.menuIndex + 1
        l = len (self.menuScripts)
        if index >= l:
            self.script_first (gesture)
            return
        self.menuIndex = index
        ui.message (','.join (self.menuScripts[index]))
    # 虚拟菜单第一项的处理
    def script_first(self, gesture):
        tones.beep (300, 20)
        self.menuIndex = 0
        ui.message (','.join (self.menuScripts[self.menuIndex]))
    # 虚拟菜单最后一项的处理
    def script_last(self, gesture):
        tones.beep (300, 20)
        self.menuIndex = len (self.menuScripts) -1
        ui.message (','.join (self.menuScripts[self.menuIndex]))
    # 当某个虚拟菜单点击的处理
    def script_activate(self, gesture):
        gesture2 = KeyboardInputGesture.fromName(self.menuScripts[self.menuIndex][1])
        if not gesture2:
            self.script_cancel (gesture)
            return
        script = self.getScript (gesture2)
        if script:
            script (gesture2)
        self.script_cancel (gesture)
    def script_cancel(self, gesture):
        self.cancelVirtualMenus ()
        tones.beep (400, 10)
    def getScript(self, gesture):
        script = globalPluginHandler.GlobalPlugin.getScript(self, gesture)
        hasNoMenus = not script
        if not self.hasNoMenus and hasNoMenus:
            self.script_cancel (gesture)
        self.hasNoMenus = hasNoMenus
        return script
    def cancelVirtualMenus (self):
        # 清空手势
        self.clearGestureBindings ()
        # 绑定入口手势
        self.bindGestures (entryGestures)
        self.hasNoMenus = True